package com.ermace.robo.jumper;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.ermace.robo.jumper.game.Map;
import com.ermace.robo.jumper.game.MapList;
import com.ermace.robo.jumper.game.GameObjects.Bitmaps;
import com.ermace.robo.jumper.game.Player.Position;

public class MapSelectionView extends SurfaceView implements SurfaceHolder.Callback {

	private selectionThread selectionThread;

	private int framesPast = 0;
	private int currentFrame = 0;
	private int toDraw = 0;
	
	public static double SCREEN_WIDTH;
	public static double SCREEN_HEIGHT;
	
	private double GROUND_LEVEL =  2 * MainActivity.getScreenHeight() / 3;
	
	private double ROBO_WIDTH =  MainActivity.getScreenWidth() / 8;
	private double ROBO_HEIGHT=  MainActivity.getScreenWidth() / 7;
	
	private double MAP_RADIUS= 2 * MainActivity.getScreenHeight() / 3;
	
	private double ARROW_RADIUS =  MainActivity.getScreenWidth() / 6;
	
	private double MAP_NAME_WIDTH = MainActivity.getScreenWidth() / 3;
	private double MAP_NAME_HEIGHT = MainActivity.getScreenHeight() / 4;
	
	private double SPEED = MainActivity.getScreenWidth() / 3;
	
	private Position robo1;
	private Position robo2;
	private Position robo3;
	
	private Position mapImagePos1;
	private Position mapImagePos2;
	
	private Position mapNamePos = new Position( 1 * MainActivity.getScreenWidth() / 2 - MAP_NAME_WIDTH / 2, 0);
	
	private boolean movingRight = false;
	private boolean movingLeft = false;
	private boolean locked = false;
	
	private static final Bitmap Spritesheet = Bitmaps.getInstance().getBitmap(R.drawable.spritesheet_mapselection);
	private static final Bitmap bckgrnd = Bitmaps.getInstance().getBitmap(R.drawable.background_menu);
	private static final Bitmap map_border = Bitmaps.getInstance().getBitmap(R.drawable.map_image_border);
	private static final Bitmap rightArrow_Bitmap = Bitmaps.getInstance().getBitmap(R.drawable.arrow_right);
	private static final Bitmap leftArrow_Bitmap = Bitmaps.getInstance().getBitmap(R.drawable.arrow_left);
	
	private ArrayList<Bitmap> mapImages;
	private ArrayList<String> mapNames;
	
	private int currentMap = 0;
	private int nextMap = 0;
	
	private Rect leftArrow = new Rect((int)((MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 - ARROW_RADIUS /2), (int)(MainActivity.getScreenHeight() / 3),(int)((MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 + ARROW_RADIUS /2),(int) (MainActivity.getScreenHeight() / 3 + ARROW_RADIUS));
	private Rect rightArrow = new Rect((int)((3*MainActivity.getScreenWidth() / 4 + MAP_RADIUS / 4 - ARROW_RADIUS /2)), (int)(MainActivity.getScreenHeight() / 3),
			(int)(3*MainActivity.getScreenWidth() / 4 + MAP_RADIUS / 4 + ARROW_RADIUS /2),(int) (MainActivity.getScreenHeight() / 3 + ARROW_RADIUS));
	
	private Activity activity;
	private Intent intent;
	
	private Paint testPaint;
	
	
	public MapSelectionView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		initParam();
		getHolder().addCallback(this);
		
		activity = (Activity) context;
		
		mapImages = new ArrayList<Bitmap>();
		mapNames = new ArrayList<String>();
		
		testPaint = new Paint();
		testPaint.setColor(Color.BLACK);
		
		for(MapList mp: MapList.values())
		{
			Map map = mp.getMap();
			mapImages.add(BitmapFactory.decodeResource(getResources(), map.getImageId()));
			mapNames.add(map.getName());
		}
	}
	
	public void setIntent(Intent intent)
	{
		this.intent = intent;	
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
				
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);

		SCREEN_WIDTH = w; // store the width
		SCREEN_HEIGHT = h; // store the height
		
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		selectionThread = new selectionThread(getHolder());
	    selectionThread.setRunning(true);
	    selectionThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
	boolean retry = true;
	selectionThread.setRunning(false);
	while(retry){
		try {
			selectionThread.join();
			retry = false;
		} catch (InterruptedException e) {
			
		}
	}
	}
	
	public void update(Canvas canvas, double elapsedTimeMS)
	{
		double interval = elapsedTimeMS / 1000.0;
				
		if(framesPast == 10)
		{
			currentFrame = ++currentFrame % 8;
			framesPast = 0;
		} else {
			framesPast +=1;
		}
		
		if(movingRight)
		{
			if(robo3.getX() > 3*MainActivity.getScreenWidth() / 4 + MAP_RADIUS / 4 - ROBO_WIDTH /2)
				initParam();
			if(robo1.getX() <  MainActivity.getScreenWidth() - ROBO_WIDTH)
			{
				robo1 = robo1.add(new Position(interval * SPEED, 0));
				robo2 = robo2.add(new Position(interval * SPEED, 0));
				robo3 = robo3.add(new Position(interval * SPEED, 0));
				if(robo1.getX() > mapImagePos1.getX() - ROBO_WIDTH)
				{
					toDraw = 3;
					mapImagePos1 = mapImagePos1.add(new Position(interval * SPEED, 0));
					mapImagePos2 = mapImagePos2.add(new Position(interval * SPEED, 0));
				}
			}
			else
			{
				toDraw = 1;
				movingRight = false;
				movingLeft = true;
			}
		}
		else if(movingLeft)
		{
			if(robo3.getX() < (MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 - ROBO_WIDTH /2)
				initParam();
			else if(robo2.getX() >  0)
			{
				robo1 = robo1.add(new Position( -interval * SPEED, 0));
				robo2 = robo2.add(new Position( -interval * SPEED, 0));
				robo3 = robo3.add(new Position( -interval * SPEED, 0));
				if(robo2.getX() < mapImagePos1.getX() + MAP_RADIUS)
				{
				toDraw = 4;
				mapImagePos1 = mapImagePos1.add(new Position( -interval * SPEED, 0));
				mapImagePos2 = mapImagePos2.add(new Position( -interval * SPEED, 0));
				}
			}
			else
				{
					toDraw = 2;
					movingLeft = false;
					movingRight = true;
				}
		}		
		if(bckgrnd != null && canvas != null)
			canvas.drawBitmap(bckgrnd, null, new Rect(0, 0, canvas.getWidth(), canvas.getHeight()), null);
		
		int height = Spritesheet.getHeight() / 5 ;
		int width = Spritesheet.getWidth() / 9;
		
		int srcX = currentFrame * width;
		int srcY = toDraw * height;

	
		canvas.drawBitmap(Spritesheet, new Rect((srcX), (srcY), srcX + width,srcY + height), new Rect((int)(robo1.getX()), (int)(robo1.getY()),
			(int)(robo1.getX() + ROBO_WIDTH),(int) (robo1.getY() + ROBO_HEIGHT)) , null);
		
		canvas.drawBitmap(Spritesheet, new Rect((srcX), (srcY), srcX + width,srcY + height), new Rect((int)(robo2.getX()), (int)(robo2.getY()),
			(int)(robo2.getX() + ROBO_WIDTH),(int) (robo2.getY() + ROBO_HEIGHT)) , null);
		
		
		canvas.drawBitmap(mapImages.get(currentMap), null , new Rect((int)(mapImagePos1.getX()) + 2, (int)(mapImagePos1.getY()) + 2,
				(int)(mapImagePos1.getX() + MAP_RADIUS) - 3,(int) (mapImagePos1.getY() + MAP_RADIUS) - 3) , null);
		
		canvas.drawBitmap(map_border, null , new Rect((int)(mapImagePos1.getX()), (int)(mapImagePos1.getY()) ,
				(int)(mapImagePos1.getX() + MAP_RADIUS),(int) (mapImagePos1.getY() + MAP_RADIUS)) , null);
		
		
		if(locked){
			
			canvas.drawBitmap(Spritesheet, new Rect((srcX), (srcY), srcX + width,srcY + height), new Rect((int)(robo3.getX()), (int)(robo3.getY()),
					(int)(robo3.getX() + ROBO_WIDTH),(int) (robo3.getY() + ROBO_HEIGHT)) , null);
			
			canvas.drawBitmap(mapImages.get(nextMap), null , new Rect((int)(mapImagePos2.getX()) + 2, (int)(mapImagePos2.getY() + 2),
					(int)(mapImagePos2.getX() + MAP_RADIUS) - 3 ,(int) (mapImagePos2.getY() + MAP_RADIUS) - 3) , null);
			
			canvas.drawBitmap(map_border, null , new Rect((int)(mapImagePos2.getX()), (int)(mapImagePos2.getY()),
					(int)(mapImagePos2.getX() + MAP_RADIUS),(int) (mapImagePos2.getY() + MAP_RADIUS)) , null);
			
			
		
		}
		else
		{
			canvas.drawBitmap(leftArrow_Bitmap, null , leftArrow, null);
			canvas.drawBitmap(rightArrow_Bitmap, null , rightArrow, null);
		
		}
		
	}
	
	public void initParam()
	{
		mapImagePos1 = new Position( 1 * MainActivity.getScreenWidth() / 2 - MAP_RADIUS / 2, 1 * MainActivity.getScreenHeight() / 2 - MAP_RADIUS /2);
		mapImagePos2 = new Position( - MAP_RADIUS, 1 * MainActivity.getScreenHeight() / 2 - MAP_RADIUS /2);
		robo1 = new Position( (MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 - ROBO_WIDTH /2, GROUND_LEVEL);
		robo2 = new Position( 3*MainActivity.getScreenWidth() / 4 + MAP_RADIUS / 4 - ROBO_WIDTH /2, GROUND_LEVEL);
		robo3 = new Position( -MAP_RADIUS - ((MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 - ROBO_WIDTH /2), GROUND_LEVEL);
		movingLeft = false;
		movingRight = false;
		locked = false;
		toDraw = 0;
		currentMap = nextMap;
	}
	
	 private class selectionThread extends Thread {
			private SurfaceHolder surfaceHolder; // for manipulating canvas
			private boolean threadIsRunning = true; // running by default

			// initializes the surface holder
			public selectionThread(SurfaceHolder holder) {
				surfaceHolder = holder;
				setName("SelectionThread");
			}

			// changes running state
			public void setRunning(boolean running) {
				threadIsRunning = running;
			}

			//controls the game loop
			@Override
			public void run() {
				Canvas canvas = null; // used for drawing
				long previousFrameTime = System.currentTimeMillis();
				while (threadIsRunning) {
					try {
						canvas = surfaceHolder.lockCanvas(null);

						// lock the surfaceHolder for drawing
						synchronized(surfaceHolder) {
							long currentTime = System.currentTimeMillis();
							double elapsedTimeMS = currentTime - previousFrameTime;
							
							update(canvas, elapsedTimeMS);
							
							previousFrameTime = currentTime; // update previous time
						}
					} finally {
						if (canvas != null)
							surfaceHolder.unlockCanvasAndPost(canvas);
					}
				}
			}
		}
	 
	public boolean handleEvent(MotionEvent event) {
		if(!locked){
			locked = true;
			
			float x = event.getX();
			float y = event.getY();
			
			
			if(rightArrow.contains((int)x, (int)y))
			{
				mapImagePos2 = new Position( - MAP_RADIUS, 1 * MainActivity.getScreenHeight() / 2 - MAP_RADIUS /2);
				robo3 = new Position( -MAP_RADIUS - ((MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 -  ROBO_WIDTH /2) - ROBO_WIDTH, GROUND_LEVEL);
				movingRight = true;
				toDraw = 2;
				
				if(currentMap == 0)
					nextMap = mapImages.size() - 1;
				else
					nextMap = currentMap - 1;
			}
			else if(leftArrow.contains((int)x, (int)y)){
				mapImagePos2 = new Position( MainActivity.getScreenWidth(), 1 * MainActivity.getScreenHeight() / 2 - MAP_RADIUS /2);
				robo3 = new Position( MainActivity.getScreenWidth() + MAP_RADIUS + ((MainActivity.getScreenWidth() - MAP_RADIUS)/ 4 - ROBO_WIDTH /2) , GROUND_LEVEL);
				movingLeft = true;
				toDraw = 1;
				
				if(currentMap == mapImages.size() - 1)
					nextMap = 0;
				else
					nextMap = currentMap + 1;
			}
			else if(new Rect((int)(mapImagePos1.getX()), (int)(mapImagePos1.getY()),(int)(mapImagePos1.getX() + MAP_RADIUS),(int) (mapImagePos1.getY() + MAP_RADIUS)).contains((int)x, (int)y))
			{
				
				intent.putExtra("currentMap", MapList.getMapByName(mapNames.get(currentMap)));
				MainActivity.startingNewActivity = true;
				activity.startActivity(intent);
				activity.finish();
			}
			else{
				locked = false;
			}
		}
		return false;
	}
	
}
